home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / crtplus.com / CRTPLUS.PAS next >
Encoding:
Pascal/Delphi Source File  |  1990-01-14  |  22.0 KB  |  767 lines

  1. {
  2.  
  3.     CrtPlus.pas
  4.     1-14-90
  5.  
  6.     Keyboard, cursor, and window enhancements to
  7.     Turbo Pascal 5.5's Crt unit.
  8.  
  9.     Copyright 1990
  10.     John W. Small
  11.     All rights reserved
  12.  
  13.     PSW / Power SoftWare
  14.     P.O. Box 10072
  15.     McLean, Virginia 22102 8072
  16.  
  17.     If you acquired the CrtPlus ToolBox through 'shareware'
  18.     and find it useful, a registration fee of $20 would
  19.     be appreciated.  Upon registion you will be sent source
  20.     code, manual on disk, the latest example programs, and
  21.     notices of updates.
  22.  
  23.     Notice:  The source code is not shareware, nor has it
  24.     been released into the public domain.  Please respect my
  25.     copyright!  Your are free to distribute crtplus.tpu,
  26.     the interface section only of crtplus.pas, and any
  27.     demos along with your own programs.  Thanks, John.
  28.  
  29.  
  30.     Works consulted:
  31.  
  32.     Norton, Peter. "Programmer's Guide to the IBM PC."
  33.             Bellevue, Washington: Microsoft Press, 1985.
  34.  
  35.     Norton, Peter. "The New Peter Norton Programmer's Guide
  36.             to the IBM PC & PS/2." Bellevue, Washington:
  37.             Microsoft Press, 1988.
  38.  
  39.     Duncan, Ray. "Advanced MS DOS.", Bellevue Washington:
  40.             Microsoft Press, 1986.
  41.  
  42.     Wilton, Richard. "Programmer's Guide to PC & PS/2
  43.             Video Systems.", Bellevue Washington:
  44.             Microsoft Press, 1987.
  45.  
  46.     Persons consulted:
  47.  
  48.     Saucci, Andrew Jr.  MegaPost via telephone conversation
  49.             on enhanced keyboard operations.
  50.  
  51. }
  52.  
  53. unit CrtPlus;
  54.  
  55. interface
  56.  
  57.     uses dos, crt;
  58.  
  59.     const
  60.  
  61.         {
  62.             The ascii codes listed below are returned by
  63.             CrtPlus.ReadKey, and by Crt.ReadKey (first call).
  64.         }
  65.  
  66.         ESC         =   #27;
  67.         CR          =   #13;
  68.         Tab         =    #9;
  69.         BackSp      =    #8;
  70.         Space       =   #32;
  71.         DelCh       =  #127;
  72.  
  73.         CtrlA       =    #1;
  74.         CtrlB       =    #2;
  75.         CtrlC       =    #3;
  76.         CtrlD       =    #4;
  77.         CtrlE       =    #5;
  78.         CtrlF       =    #6;
  79.         CtrlG       =    #7;
  80.         CtrlH       =    #8;
  81.         CtrlI       =    #9;
  82.         CtrlJ       =   #10;
  83.         CtrlK       =   #11;
  84.         CtrlL       =   #12;
  85.         CtrlM       =   #13;
  86.         CtrlN       =   #14;
  87.         CtrlO       =   #15;
  88.         CtrlP       =   #16;
  89.         CtrlQ       =   #17;
  90.         CtrlR       =   #18;
  91.         CtrlS       =   #19;
  92.         CtrlT       =   #20;
  93.         CtrlU       =   #21;
  94.         CtrlV       =   #22;
  95.         CtrlW       =   #23;
  96.         CtrlX       =   #24;
  97.         CtrlY       =   #25;
  98.         CtrlZ       =   #26;
  99.  
  100.         {
  101.             EnhKey is returned by CrtPlus.EnhReadKey
  102.             whenever a 101/102 keyboard enhanced key stroke
  103.             is reported.  The scan code of the enhanced key
  104.             remains the same as that  reported on 83/84
  105.             keyboards and by CrtPlus.ReadKey, only #224 is
  106.             returned instead of #0 as the ascii character.
  107.  
  108.             There are several exceptions:
  109.  
  110.                 F11/12  EnhReadKey returns ascii #0.
  111.  
  112.             If the enhanced key stroke replicates a regular
  113.             ascii character then EnhReadKey returns that
  114.             ascii character and #224 as the scan code via
  115.             CrtPlus.asciiScan high byte, e.g.
  116.  
  117.                 Enter (keypad)  ascii = #13, scan = #224.
  118.                 Enter (regular) ascii = #13, scan = #28.
  119.  
  120.         }
  121.  
  122.         EnhKey      =   #224;
  123.  
  124.  
  125.  
  126.         {
  127.             The scan codes listed below are returned when
  128.             (CrtPlus.ReadKey = #0) via the global variable,
  129.             CrtPlus.asciiScan, i.e.
  130.  
  131.                 char(hi(CrtPlus.asciiScan)),
  132.  
  133.             or by Crt.ReadKey (second call).  Please note
  134.             that CrtPlus.ReadKey requires only one call
  135.             since the extended character set characters are
  136.             returned in high byte of CrtPlus.asciiScan.
  137.             CrtPlus.ReadKey is faster than Crt.ReadKey since
  138.             it is inline code which also explains why I
  139.             couldn't make the keyboard into an object.
  140.         }
  141.  
  142.         AltA        =    #30;
  143.         AltB        =    #48;
  144.         AltC        =    #46;
  145.         AltD        =    #32;
  146.         AltE        =    #18;
  147.         AltF        =    #33;
  148.         AltG        =    #34;
  149.         AltH        =    #35;
  150.         AltI        =    #23;
  151.         AltJ        =    #36;
  152.         AltK        =    #37;
  153.         AltL        =    #38;
  154.         AltM        =    #50;
  155.         AltN        =    #49;
  156.         AltO        =    #24;
  157.         AltP        =    #25;
  158.         AltQ        =    #16;
  159.         AltR        =    #19;
  160.         AltS        =    #31;
  161.         AltT        =    #20;
  162.         AltU        =    #22;
  163.         AltV        =    #47;
  164.         AltW        =    #17;
  165.         AltX        =    #45;
  166.         AltY        =    #21;
  167.         AltZ        =    #44;
  168.  
  169.         Home        =    #71;
  170.         UpArr       =    #72;
  171.         PgUp        =    #73;
  172.         LArr        =    #75;
  173.         RArr        =    #77;
  174.         EndKey      =    #79;
  175.         DnArr       =    #80;
  176.         PgDn        =    #81;
  177.         InsKey      =    #82;
  178.         DelKey      =    #83;
  179.  
  180.         CtrlHome    =    #119;
  181.         CtrlPgUp    =    #132;
  182.         CtrlLArr    =    #115;
  183.         CtrlRArr    =    #116;
  184.         CtrlEnd     =    #117;
  185.         CtrlPgDn    =    #118;
  186.  
  187.  
  188.         Alt1        =    #120;
  189.         Alt2        =    #121;
  190.         Alt3        =    #122;
  191.         Alt4        =    #123;
  192.         Alt5        =    #124;
  193.         Alt6        =    #125;
  194.         Alt7        =    #126;
  195.         Alt8        =    #127;
  196.         Alt9        =    #128;
  197.         Alt0        =    #129;
  198.  
  199.         AltHyphen   =    #130;
  200.         AltEquals   =    #131;
  201.         CtrlPrtSc   =    #114;
  202.         ShiftTab    =     #15;
  203.  
  204.  
  205.         F1          =     #59;
  206.         ShiftF1     =     #84;
  207.         CtrlF1      =     #94;
  208.         AltF1       =    #104;
  209.  
  210.         F2          =     #60;
  211.         ShiftF2     =     #85;
  212.         CtrlF2      =     #95;
  213.         AltF2       =    #105;
  214.  
  215.         F3          =     #61;
  216.         ShiftF3     =     #86;
  217.         CtrlF3      =     #96;
  218.         AltF3       =    #106;
  219.  
  220.  
  221.         F4          =     #62;
  222.         ShiftF4     =     #87;
  223.         CtrlF4      =     #97;
  224.         AltF4       =    #107;
  225.  
  226.         F5          =     #63;
  227.         ShiftF5     =     #88;
  228.         CtrlF5      =     #98;
  229.         AltF5       =    #108;
  230.  
  231.         F6          =     #64;
  232.         ShiftF6     =     #89;
  233.         CtrlF6      =     #99;
  234.         AltF6       =    #109;
  235.  
  236.         F7          =     #65;
  237.         ShiftF7     =     #90;
  238.         CtrlF7      =    #100;
  239.         AltF7       =    #110;
  240.  
  241.         F8          =     #66;
  242.         ShiftF8     =     #91;
  243.         CtrlF8      =    #101;
  244.         AltF8       =    #111;
  245.  
  246.         F9          =     #67;
  247.         ShiftF9     =     #92;
  248.         CtrlF9      =    #102;
  249.         AltF9       =    #112;
  250.  
  251.         F10         =     #68;
  252.         ShiftF10    =     #93;
  253.         CtrlF10     =    #103;
  254.         AltF10      =    #113;
  255.  
  256.         {
  257.             Returned via char(hi(CrtPlus.asciiScan)) only
  258.             after call to CrtPlus.EnhReadKey returns $E0.
  259.         }
  260.  
  261.         F11         =    #133;
  262.         ShiftF11    =    #135;
  263.         CtrlF11     =    #137;
  264.         AltF11      =    #139;
  265.  
  266.         F12         =    #134;
  267.         ShiftF12    =    #136;
  268.         CtrlF12     =    #138;
  269.         AltF12      =    #140;
  270.  
  271.  
  272.         {
  273.             BIOS keyboard shift constants used to mask value
  274.             returned by CrtPlus.ReadShift and
  275.             CrtPlus.EnhReadShift, e.g.
  276.  
  277.                 if boolean(CapsLock and ReadShift) then ...
  278.         }
  279.  
  280.         InsertState         =   $0080;
  281.         CapsLock            =   $0040;
  282.         NumLock             =   $0020;
  283.         ScrollLock          =   $0010;
  284.         AltPressed          =   $0008;
  285.         CtrlPressed         =   $0004;
  286.         LeftShiftPressed    =   $0002;
  287.         RightShiftPressed   =   $0001;
  288.         ShiftPressed        =   $0003;
  289.  
  290.  
  291.         {
  292.             BIOS extended keyboard shift constants used to
  293.             mask value return by CrtPlus.EnhReadShift, e.g.
  294.  
  295.                 if boolean(CapsLock and EnhReadShift)
  296.                     then ...
  297.         }
  298.  
  299.         SysReqPressed       =   $8000;
  300.         CapsLockPressed     =   $4000;
  301.         NumLockPressed      =   $2000;
  302.         ScollLockPressed    =   $1000;
  303.         RightAltPressed     =   $0800;
  304.         RightCtrlPressed    =   $0400;
  305.         LeftAltPressed      =   $0200;
  306.         LeftCtrlPressed     =   $0100;
  307.  
  308.  
  309.         {
  310.             Typematic Rate and Delay Constants to be used
  311.             with call to CrtPlus.EnhSetTypeMatic().
  312.  
  313.             TMR218 represents:
  314.  
  315.                 Typematic Rate of 21.8 char/sec.
  316.  
  317.             TMD750 represents
  318.  
  319.                 Typematic Delay of 750 millisec.
  320.         }
  321.  
  322.         TMR300  =   $00;
  323.         TMR267  =   $01;
  324.         TMR240  =   $02;
  325.         TMR218  =   $03;
  326.         TMR200  =   $04;
  327.         TMR185  =   $05;
  328.         TMR171  =   $06;
  329.         TMR160  =   $07;
  330.         TMR150  =   $08;
  331.         TMR133  =   $09;
  332.         TMR120  =   $0A;
  333.         TMR109  =   $0B;
  334.         TMR100  =   $0C;
  335.         TMR092  =   $0D;
  336.         TMR086  =   $0E;
  337.         TMR080  =   $0F;
  338.         TMR075  =   $10;
  339.         TMR067  =   $11;
  340.         TMR060  =   $12;
  341.         TMR055  =   $13;
  342.         TMR050  =   $14;
  343.         TMR046  =   $15;
  344.         TMR043  =   $16;
  345.         TMR040  =   $17;
  346.         TMR037  =   $18;
  347.         TMR033  =   $19;
  348.         TMR030  =   $1A;
  349.         TMR027  =   $1B;
  350.         TMR025  =   $1C;
  351.         TMR023  =   $1D;
  352.         TMR021  =   $1E;
  353.         TMR020  =   $1F;
  354.  
  355.         TMD250  =   $00;
  356.         TMD500  =   $01;
  357.         TMD750  =   $02;
  358.         TMD1000 =   $03;
  359.  
  360.  
  361.     type
  362.  
  363.         {
  364.             TextFrameChars are the IBM extended character
  365.             set characters used to draw line boxes.  Imagine
  366.             a box with a cross inside, then the characters
  367.             needed to draw this are typified by the corners
  368.             of the box, the four points the cross touches
  369.             the outside box, and the center of the cross.
  370.  
  371.             Indices into textFrameChars are thus:
  372.  
  373.                 rt = top-right corner of the box,
  374.                 mm = middle-middle or center of cross,
  375.                 mb = middle-bottom where cross touches
  376.                         the bottom of the box
  377.                 etc.
  378.         }
  379.  
  380.         textFrameChars = (v,h,lt,rt,rb,lb,ml,mt,mr,mb,mm);
  381.  
  382.         textFrame = array[textFrameChars] of char;
  383.  
  384.     const
  385.  
  386.         {
  387.             Text Box Drawing Characters:
  388.  
  389.                 svsh = single vert., single horizonal lines
  390.                 dvdh = double vert., double horizonal lines
  391.                 etc.
  392.         }
  393.  
  394.         svsh : textFrame =
  395.             #179#196#218#191#217#192#195#194#180#193#197;
  396.         svdh : textFrame =
  397.             #179#205#213#184#190#212#198#209#181#207#216;
  398.         dvsh : textFrame =
  399.             #186#196#214#183#189#211#199#210#182#208#215;
  400.         dvdh : textFrame =
  401.             #186#205#201#187#188#200#204#203#185#202#206;
  402.  
  403.     type
  404.  
  405.  
  406.         { Cursor object for turning on/off cursor, etc. }
  407.  
  408.         CursorShape = object                { CURSORSHAPE }
  409.             OrigShape, prevShape : word;
  410.             procedure init;     { Do not call! }
  411.             function  getShape : word;
  412.             procedure putShape (shape : word);
  413.             function  defaultShape : word;
  414.             procedure off;
  415.             procedure on;
  416.             procedure block;
  417.             procedure normal;
  418.             procedure restore;
  419.             procedure done;
  420.         end;
  421.  
  422.  
  423.  
  424.         { Object for storing text screen images. }
  425.  
  426.         TextImage = object                  { TEXTIMAGE }
  427.             ImageMin, ImageMax : word;
  428.             image : ^word;
  429.             procedure init (x1, y1, x2, y2 : byte);
  430.             procedure done
  431.         end;
  432.  
  433.  
  434.  
  435.         {
  436.             Turbo Pascal's text-screen state, i.e. current
  437.             window, text attribute, cursor position, and
  438.             cursor shape.
  439.         }
  440.  
  441.         TurboWindow = object                { TURBOWINDOW }
  442.             WindMin, WindMax : word;
  443.             textAttr, wherex, wherey : byte;
  444.             curshape : word;
  445.             procedure save;
  446.             procedure restore;
  447.         end;
  448.  
  449.  
  450.  
  451.         {
  452.             TextWindow is a direct replacement for Turbo
  453.             Pascal's window procedure.  It sets the current
  454.             window, like Turbo Pascal does, but it also
  455.             saves the shadow beneath the window and the
  456.             screen state before the window was called.  When
  457.             done is called the window is removed and the
  458.             screen returned to its previous state.  Call
  459.             TxtScr.TextMode() instead of Crt.TextMode()
  460.             when changing video modes to insure proper
  461.             operation!
  462.         }
  463.  
  464.         TextWindow = object                 { TEXTWINDOW }
  465.             shadow : TextImage;
  466.             prevWind  : TurboWindow;
  467.             procedure window (x1, y1, x2, y2 : byte);
  468.             procedure done
  469.         end;
  470.  
  471.  
  472.  
  473.         {
  474.             The TextScreen object provides enhancements to
  475.             Turbo Pascal's Crt unit's treatment of the text
  476.             screen.  The TextScreen object works in all the
  477.             text modes supported by Turbo Pascal including
  478.             43/50 line modes!  It also respects the setting
  479.             of Crt.CheckSnow and Crt.DirectVideo!  The only
  480.             restriction is that your call TxtScr.TextMode()
  481.             instead of Crt.TextMode() when changing video
  482.             modes.
  483.         }
  484.  
  485.         TextScreen = object                 { TEXTSCREEN }
  486.  
  487.             OrigMode, dim, vseg, vport : word;
  488.             prevTextAttr : byte;
  489.             state : TextWindow; { used by save and restore }
  490.             CheckSnow, DirectVideo : boolean;
  491.             vmode : integer;
  492.  
  493.             procedure init;     { Do not call! }
  494.  
  495.  
  496.             { Use to save screen during exec calls. }
  497.  
  498.             procedure save;
  499.             procedure restore;
  500.  
  501.  
  502.             { Use instead of Crt.TextMode(). }
  503.  
  504.             procedure TextMode  (mode : integer);
  505.             function  VideoMode : integer;
  506.             function  IsTextMode : boolean;
  507.             function  IsColorMode : boolean;
  508.  
  509.  
  510.             { Use to extend Low/Norm/High video. }
  511.  
  512.             procedure ReverseVideo;
  513.             procedure SetVideo  (fgrd, bgrd : byte);
  514.             procedure BlinkVideo;
  515.             procedure UnblinkVideo;
  516.             procedure RestoreVideo;
  517.  
  518.  
  519.             { Use to construct TextAttr bytes. }
  520.  
  521.             function  rvideo (attr : byte) : byte;
  522.             function  svideo (fgrd, bgrd : byte) : byte;
  523.             function  bvideo (attr : byte) : byte;
  524.             function  ubvideo (attr : byte) : byte;
  525.             function  lvideo (attr : byte) : byte;
  526.             function  hvideo (attr : byte) : byte;
  527.  
  528.  
  529.             { Use to save and restore screen images. }
  530.  
  531.             procedure getText   (var ti : TextImage);
  532.             procedure putText   (var ti : TextImage);
  533.  
  534.  
  535.             {
  536.                 Use instead of WhereX and WhereY for
  537.                 screen coordinates.
  538.             }
  539.  
  540.             function  scrX : byte;
  541.             function  scrY : byte;
  542.  
  543.  
  544.             { Use to write to screen without scroll/wrap. }
  545.  
  546.             procedure scrWrite  (
  547.                 x, y, maxLen, attr : byte;
  548.                 var str : string);
  549.             procedure scrFill   (
  550.                 x, y, len, attr : byte; ch : char);
  551.                 { Note: if ch = #0 then fill attr only }
  552.             procedure scrHorzLn (
  553.                 left, row, right, attr: byte; ch: char);
  554.             procedure scrVertLn (
  555.                 col, top, bottom, attr: byte; ch: char);
  556.             procedure scrBox    (
  557.                 x1, y1, x2, y2, attr: byte;
  558.                 var tf : textFrame);
  559.  
  560.  
  561.             {
  562.                 Use to write to current crt.window without
  563.                 scroll/wrap
  564.             }
  565.  
  566.             procedure windWrite (var str : string);
  567.             procedure windLightBar (x, y, len, attr : byte);
  568.             procedure windColor (fgrd, bgrd : byte);
  569.  
  570.  
  571.             {  Call to restore original crt mode. }
  572.  
  573.             procedure done
  574.         end;
  575.  
  576.  
  577.  
  578.         {
  579.             FramedTextWindow is a popup window object drived
  580.             from the TextWindow object.  This window has an
  581.             optional border, title and/or footer, and scroll
  582.             bar(s).  This object provides an example of how
  583.             the TextWindow object is extensible and can be
  584.             used as a base class object to construct any
  585.             type of text window!  Call TxtScr.TextMode()
  586.             instead of Crt.TextMode() when changing video
  587.             modes to insure proper operation!
  588.         }
  589.  
  590.                                     { FRAMEDTEXTWINDOW }
  591.  
  592.         FramedTextWindow = object(TextWindow)
  593.             procedure window (x1, y1, x2, y2 : byte);
  594.             procedure frame  (
  595.                 attr : byte; var f : textFrame);
  596.             procedure titleFooter (
  597.                 title : boolean; attr : byte; str : string);
  598.             procedure scrollBar (
  599.                 vert : boolean; attr : byte;
  600.                 var f : textFrame; p, maxp : integer);
  601.             { Uses procedure TextWindow.done; }
  602.         end;
  603.  
  604.  
  605.  
  606.         {
  607.             ShadowTextWindow is yet another popup window
  608.             object drived from the TextWindow object.  This
  609.             window has an title bar and shadow beneath the
  610.             window.  This object is yet another extension to
  611.             the TextWindow object.  Call TxtScr.TextMode()
  612.             instead of Crt.TextMode() when changing video
  613.             modes to insure proper operation!
  614.         }
  615.  
  616.                                     { SHADOWWINDOW }
  617.  
  618.         ShadowTextWindow = object(TextWindow)
  619.             procedure window(x1, y1, x2, y2 : byte);
  620.             procedure title(attr : byte; str : string);
  621.             { Uses procedure TextWindow.done; }
  622.         end;
  623.  
  624.  
  625.     var
  626.  
  627.         cursor : CursorShape;   { TEXT CURSOR OBJECT }
  628.  
  629.         TxtScr : TextScreen;    { TEXT SCREEN OBJECT }
  630.  
  631.         {
  632.             AsciiScan contains the keystroke's ascii code
  633.             in the low byte and scan code in the high byte.
  634.             It is set on every call to CrtPlus.ReadKey/
  635.             EnhReadKey/KeyPressed/EnhKeyPressed.
  636.             CrtPlus.EnhWriteKey writes this word back into
  637.             the keyboard buffer.
  638.         }
  639.  
  640.         asciiScan : word;
  641.  
  642.  
  643.  
  644.  
  645.     {
  646.         Do not mix calls between Crt.ReadKey/Keypressed with
  647.         CrtPlus keyboard routines!
  648.     }
  649.  
  650.  
  651.     {
  652.         READ CHARACTER FROM KEYBOARD, BIOS intr $16, fnc $00
  653.  
  654.         Example:
  655.  
  656.         var ch : char;
  657.         begin
  658.             case CrtPlus.ReadKey of
  659.                 #0: case char(hi(CrtPlus.asciiScan)) of
  660.                         LArr : ... ;
  661.                         RArr : ... ;
  662.                         PgUp : ... ;
  663.                         ...
  664.                     end;
  665.                 CR : ... ;
  666.                 ESC : ... ;
  667.             else
  668.                 ch := char(lo(CrtPlus.asciiScan));
  669.                 ...
  670.             end;
  671.             ...
  672.         end;
  673.     }
  674.  
  675.     function  ReadKey : char;
  676.                 inline($30/$E4/             { xor ah,ah }
  677.                     $CD/$16/                { int $16   }
  678.                     $89/$06/CrtPlus.asciiScan);
  679.                                     { mov asciiScan,ax }
  680.  
  681.  
  682.     { IS CHARACTER WAITING? BIOS intr $16, fnc $01 }
  683.     { Sets CrtPlus.asciiScan just like CrtPlus.ReadKey. }
  684.  
  685.     function  KeyPressed : boolean;
  686.  
  687.  
  688.     { READ KEYBOARD SHIFT STATE.  BIOS intr $16, fnc $02 }
  689.  
  690.     function  ReadShift : word;
  691.                 inline($B4/$02/         { mov ah,2  }
  692.                     $CD/$16/            { int $16   }
  693.                     $30/$E4);           { xor ah,ah }
  694.  
  695.  
  696.  
  697.     {
  698.         ATTENTION!!!
  699.  
  700.         Keyboard routines with "Enh" prefixes can only
  701.         be used on machines as follows:
  702.  
  703.             XT with BIOS dated 01/10/86 and later,
  704.             AT with BIOS dated 11/15/85 and later, and
  705.             PS/2s.
  706.  
  707.         The EnhSetTypeMatic routine can also be used on
  708.         the PCjr but not the XT!
  709.  
  710.         The extended keyboard routines were designed to
  711.         return character codes and scan codes for the
  712.         AT's and PS/2's enhanced keyboard.  I haven't
  713.         found a realiable way to determine the presence
  714.         of the enhanced keyboard since many clones don't
  715.         have BIOS date strings or machine IDs.  If you
  716.         have to use them do, but it's up to your program
  717.         to decide if it's okay.
  718.     }
  719.  
  720.  
  721.  
  722.     { SET TYPEMATIC RATE AND DELAY }
  723.     { BIOS intr $16, fnc $03 }
  724.     { Use only on PCjr, AT w/bios > 11/15/85, & PS/2 }
  725.  
  726.     procedure EnhSetTypeMatic(TMrate, TMdelay : byte);
  727.  
  728.  
  729.     { WRITE EXTENDED CHARACTER TO KEYBOARD }
  730.     { BIOS intr $16, fnc $05 }
  731.  
  732.     procedure EnhWriteKey;
  733.                 inline($B4/$05/         { mov ah,5  }
  734.                     $8B/$06/CrtPlus.asciiScan/
  735.                                     { mov ax,asciiScan }
  736.                     $CD/$16);           { int $16   }
  737.  
  738.  
  739.     { READ EXTENDED CHARACTER FROM KEYBOARD }
  740.     { BIOS intr $16, fnc $10 }
  741.  
  742.     function  EnhReadKey : char;
  743.                 inline($B4/$10/             { mov ah,$10 }
  744.                     $CD/$16/                { int $16   }
  745.                     $89/$06/CrtPlus.asciiScan);
  746.                                     { mov asciiScan,ax }
  747.  
  748.     { IS EXTENDED CHARACTER WAITING? }
  749.     { BIOS intr $16, fnc $11 }
  750.  
  751.     function  EnhKeyPressed : boolean;
  752.  
  753.  
  754.     { READ EXTENDED KEYBOARD SHIFT STATE }
  755.     { BIOS intr $16, fnc $12 }
  756.  
  757.     function  EnhReadShift : word;
  758.                 inline($B4/$12/         { mov ah,$12}
  759.                     $CD/$16);           { int $16   }
  760.  
  761.  
  762.  
  763.     { FLUSH KEYBOARD BUFFER }
  764.  
  765.     procedure ClrKey;
  766.  
  767.